#include "GateServer.h"
#include "../../include/GTProto.h"
#include "EndianCast.h"
#include "PlayerMgr.h"
#include "PipeManager.h"
#include <ut_debug.h>


CGateServer::CGateServer( utility::network::pipe * pPipe ) : IServer(pPipe)
{
    m_nUserCount = 0;
    m_nListnerPort = 0;
}


CGateServer::~CGateServer(void)
{
}

void CGateServer::Release()
{
    delete this;
}

void CGateServer::on_receive( const char * message, uint32 message_length )
{
    uint32 nMsgID = ntohl(*(uint32 *)message);
    _on_receieve(nMsgID, message + sizeof(uint32), message_length - sizeof(uint32));
}

void CGateServer::on_established()
{
    m_bAvailable = true;
    CGateServerMgr::Instance()->Register(this);
    LOG(INFO) << "Connected with gate server : "<< utility::network::idtoa(m_pPipe->get_remote_id());
}

void CGateServer::on_disconnected()
{
    m_bAvailable = false;
    CGateServerMgr::Instance()->UnRegister(this);
    CPipeManager::Instance()->Remove(m_pPipe->get_remote_id());
    LOG(INFO) << "disconnected from gate server : "<< utility::network::idtoa(m_pPipe->get_remote_id());
}

void CGateServer::on_error( int32 error_code, const char * error_message )
{
    on_disconnected();
}

bool CGateServer::IsAvailable()
{
    return m_bAvailable;
}

uint32 CGateServer::GetIpAddress()
{
    return m_pPipe->get_remote_ip();
}

uint16 CGateServer::GetPort()
{
    return m_nListnerPort;
}

uint16 CGateServer::GetUserCount()
{
    return m_nUserCount;
}

void CGateServer::Send( uint32 nMsgID, void * message, size_t message_size )
{
    size_t nBufSize = sizeof(nMsgID) + message_size;
    char * buf = (char *)alloca(nBufSize);
    *(uint32 *)buf = htonl(nMsgID);
    memcpy(buf + sizeof(uint32), message, message_size);
    send(buf, nBufSize);
}

void CGateServer::_on_receieve( uint32 nMsgID, const char * message, size_t message_size )
{
    switch(nMsgID)
    {
    case GT_FORWARD_NTF_ID:
        {
            GT_FORWARD_NTF_PKG * pkg = (GT_FORWARD_NTF_PKG*)message;
            CPlayer * pPlayer = CPlayerMgr::Instance()->Find(ntohll(pkg->nProxyID));
            if (pPlayer)
            {

            }
        }
        break;
    case GT_NOTIFY_USER_ONLINE_NTF_ID:
        {
            GT_NOTIFY_USER_ONLINE_NTF_PKG * pkg = (GT_NOTIFY_USER_ONLINE_NTF_PKG *)message;
            CPlayerMgr::Instance()->AddPlayer(
                ntohll(pkg->nProxyID),
                ntohl(pkg->nUserID)
                );
        }
        break;
    case GT_NOTIFY_USER_OFFLINE_NTF_ID:
        {
            GT_NOTIFY_USER_OFFLINE_NTF_PKG * pkg = (GT_NOTIFY_USER_OFFLINE_NTF_PKG *)message;
            CPlayerMgr::Instance()->Remove(ntohll(pkg->nProxyID));
        }
        break;
    }
}

/************************************************************************/
/* class CGateServerMgr                                                 */
/************************************************************************/
void CGateServerMgr::Register( CGateServer * pGateServer)
{
    m_gateServers.insert(pGateServer);
}

void CGateServerMgr::UnRegister( CGateServer * pGateServer)
{
    m_gateServers.erase(pGateServer);
}
